package org.ofdrw.sign.signContainer;

import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.MessageDigest;
import java.security.cert.Certificate;

import org.bouncycastle.asn1.DERBitString;
import org.bouncycastle.asn1.gm.GMObjectIdentifiers;
import org.bouncycastle.jcajce.provider.digest.SM3;
import org.ofdrw.gm.ses.v4.SES_Signature;
import org.ofdrw.gm.ses.v4.SESeal;
import org.ofdrw.gm.ses.v4.TBS_Sign;
import org.ofdrw.sign.SigType;
import org.ofdrw.sign.timestamp.TimeStampHook;

public class SESV4ContainerV2 {

	/**
	 * 电子印章
	 */
	private final SESeal seal;

	/**
	 * 签章使用的证书
	 */
	private final Certificate certificate;

	/**
	 * 时间戳hook对象
	 */
	private TimeStampHook timeStampHook;

	public SESV4ContainerV2(SESeal seal, Certificate signCert) {
		this.seal = seal;
		this.certificate = signCert;
	}

	public SESV4ContainerV2(SESeal seal, Certificate signCert, TimeStampHook timeStampHook) {
		this.seal = seal;
		this.certificate = signCert;
		this.timeStampHook = timeStampHook;
	}

	public MessageDigest getDigestFnc() {
		return new SM3.Digest();
	}

	/**
	 * 
	 * @param toSign
	 *            待p1签名的值
	 * @param p1
	 *            toSign 私钥签名结果
	 * @return
	 * @throws IOException
	 * @throws GeneralSecurityException
	 */
	public byte[] sign(TBS_Sign toSign, byte[] p1) throws IOException, GeneralSecurityException {

		SES_Signature signature = new SES_Signature().setToSign(toSign).setCert(certificate)
				.setSignatureAlgID(GMObjectIdentifiers.sm2sign_with_sm3).setSignature(p1);

		if (timeStampHook != null) {
			byte[] timeStamp = timeStampHook.apply(p1);
			if (timeStamp != null) {
				signature.setTimeStamp(new DERBitString(timeStamp));
			}
		}

		return signature.getEncoded("DER");
	}

	public byte[] getSeal() throws IOException {
		return seal.getEncoded("DER");
	}

	public SigType getSignType() {
		return SigType.Seal;
	}

}
